package tr.edu.yildiz.ce.dap.appagent.command.deployment.base;

import tr.edu.yildiz.ce.dap.appagent.command.deployment.agent.LocalCommand;
import tr.edu.yildiz.ce.dap.appagent.conf.DynamicProxyConfiguration;
import tr.edu.yildiz.ce.dap.appagent.exception.AgentCommunicationException;
import tr.edu.yildiz.ce.dap.appagent.exception.AgentMessageException;
import tr.edu.yildiz.ce.dap.appagent.exception.AgentRetryException;
import tr.edu.yildiz.ce.dap.appagent.exception.BasicAgentException;
import tr.edu.yildiz.ce.dap.appagent.model.DapMessage;
import tr.edu.yildiz.ce.dap.appagent.process.DeploymentProcess;
import tr.edu.yildiz.ce.dap.appagent.process.base.AbstractProcess;
import tr.edu.yildiz.ce.dap.appagent.service.MessageConverter;
import tr.edu.yildiz.ce.dap.appagent.service.infra.NetworkManager;
import tr.edu.yildiz.ce.dap.appagent.util.AgentProperties;

public abstract class AbstractAgentCommand extends AbstractCommand{

	public AbstractAgentCommand(AbstractProcess process) {
		super(process);
	}

	@Override
	public DapMessage execute(DapMessage msg) throws BasicAgentException {
		DapMessage responseMsg = null;
		boolean retry = true;
		while (retry){
			try{
				prepareRequest(msg);
				if (!(this instanceof LocalCommand)){
					try {
						NetworkManager networkManager = (NetworkManager) getProcess().getProcessManager().getService(NetworkManager.class.getName());
						String msgStr = networkManager.sendMessage(	MessageConverter.convertToXML(msg), 
															DynamicProxyConfiguration.getInstance().getProxyAddress(), 
															DynamicProxyConfiguration.getInstance().getPort());
						responseMsg = MessageConverter.convertToObject(msgStr);
					} catch (AgentCommunicationException e) {
						throw e;
					} catch (AgentMessageException e) {
						throw e;
					}
					processResponse(responseMsg);
					retry = false;
				}
			}catch (AgentRetryException e) {
				if (e.needsRetry()){
					try {
						Thread.currentThread().sleep(500);
					} catch (InterruptedException e1) {
						e1.printStackTrace();
					}
				}
			}
			
		}
		return responseMsg;
	}
	
	protected abstract void prepareRequest(DapMessage msg) throws BasicAgentException;
	
	protected abstract void processResponse(DapMessage responseMsg) throws BasicAgentException,AgentRetryException;

}
